﻿using Microsoft.Extensions.Logging;
using Warehouse.Services.Repository;
using WCS.Entities;
using WCS.IServices;

namespace WCS.Services.CommandService
{

    public class BaseCommand : INoticeCommand
    {
        protected readonly ILogger<BaseCommand> logger;
        protected readonly Repository<Job> basicTaskRepository;

        public BaseCommand(ILogger<BaseCommand> logger, Repository<Job> basicTaskRepository)
        {
            this.logger = logger;
            this.basicTaskRepository = basicTaskRepository;
        }

        //public virtual async Task<bool> DoAction(Robot robot, TransferPort port)
        //{
        //    try
        //    {
        //        var obj = GetType().GetCustomAttributes(true).FirstOrDefault(x => x is CommandAttribute);
        //        if (obj != null)
        //        {
        //            var attr = obj as CommandAttribute;
        //            if (attr.IsOnlyUpdate)
        //                return await UpdateTaskStatus(robot, attr.RobotStates, attr.TaskStates);
        //            else if (attr.IsOnlyAction)
        //            {
        //                return await Dock(robot, port, attr);
        //            }
        //            else
        //            {
        //                var result = await Dock(robot, port, attr);
        //                if (result)
        //                {
        //                    return await UpdateTaskStatus(robot, attr.RobotStates, attr.TaskStates);
        //                }
        //                else
        //                {
        //                    await UpdateTaskStatus(robot, attr.RobotStates);
        //                    return result;
        //                }

        //            }
        //        }
        //        else
        //            return false;
        //    }
        //    catch (Exception ex)
        //    {
        //        logger.LogError($"error info: {ex.Message}");
        //        return false;
        //    }

        //}

        public virtual async Task<bool> DoAction(TransferPort port)
        {
            try
            {
                var obj = GetType().GetCustomAttributes(true).FirstOrDefault(x => x is CommandAttribute);
                if (obj != null)
                {
                    var attr = obj as CommandAttribute;
                    if (attr.IsOnlyUpdate)
                        return await UpdateTaskStatus(attr.RobotStates, attr.TaskStates);
                    else if (attr.IsOnlyAction)
                    {
                        return await Dock(port, attr);
                    }
                    else
                    {
                        var result = await Dock(port, attr);
                        if (result)
                        {
                            return await UpdateTaskStatus(attr.RobotStates, attr.TaskStates);
                        }
                        else
                        {
                            await UpdateTaskStatus(attr.RobotStates);
                            return result;
                        }

                    }
                }
                else
                    return false;
            }
            catch (Exception ex)
            {
                logger.LogError($"error info: {ex.Message}");
                return false;
            }

        }

        protected virtual async Task<bool> Dock(TransferPort port, CommandAttribute attribute)
        {
            //写入AGV值
            if (await port.CheckRealAgvValueAsync(attribute.NoticeIndex, null, logger))
            {
                if (attribute?.NoticeIndex != -1)
                {
                    return await port.CheckRealPlcValueAsync(attribute.NoticeIndex, null, logger);
                }
                else
                {
                    return true;
                }
            }
            else
            {
                logger.LogWarning("Robot{0} excute {1} notice target-{1} failed!", null, GetType().Name, port.Name);
                return false;
            }

        }

        //protected virtual async Task<bool> Dock (Robot robot, TransferPort port, CommandAttribute attribute)
        //{


        //    //写入AGV值
        //    if (await port.CheckRealAgvValueAsync(attribute.NoticeIndex, robot.IP, logger))
        //    {
        //        if (attribute?.NoticeIndex != -1)
        //        {
        //            return await port.CheckRealPlcValueAsync(attribute.NoticeIndex, robot.IP, logger);
        //        }
        //        else
        //        {
        //            return true;
        //        }

        //    }
        //    else
        //    {
        //        logger.LogWarning("Robot{0} excute {1} notice target-{1} failed!", robot.IP, GetType().Name, port.Name);
        //        return false;
        //    }

        //}

        protected virtual async Task<bool> UpdateTaskStatus(RobotStatus robotStatus, TaskState taskStatus = TaskState.None)
        {
            try
            {
                await basicTaskRepository.Context.AsTenant().BeginTranAsync();


                await basicTaskRepository.Context.AsTenant().CommitTranAsync();
                return true;
            }
            catch (Exception ex)
            {
                logger.LogError($"异常信息：{ex.Message}");
                await basicTaskRepository.Context.AsTenant().RollbackTranAsync();
                return false;
            }
        }

        //protected virtual async Task<bool> UpdateTaskStatus(Robot robot, RobotStatus robotStatus, TaskState taskStatus = TaskState.None)
        //{
        //    if (robot.CurrentJob == null)
        //        return true;
        //    try
        //    {
        //        await basicTaskRepository.Context.AsTenant().BeginTranAsync();
        //        //更改AGV状态和任务状态
        //        if (taskStatus != TaskState.None)
        //        {
        //            robot.VirtualStatus = robotStatus;
        //            robot.CurrentJob.Status = taskStatus;
        //        }

        //        robot.CurrentJob.UpdateTime = DateTime.Now;
        //        await basicTaskRepository.UpdateAsync(robot.CurrentJob);
        //        await basicTaskRepository.Context.Updateable(robot).ExecuteCommandAsync();
        //        await basicTaskRepository.Context.AsTenant().CommitTranAsync();
        //        return true;
        //    }
        //    catch (Exception ex)
        //    {
        //        logger.LogError("Robot({0}) arrived the target({1}) update job-({2}),the reason is:{3}", robot.IP, robot.CurrentJob.Target, robot.CurrentJob.Id, ex.Message);
        //        await basicTaskRepository.Context.AsTenant().RollbackTranAsync();
        //        return false;
        //    }
        //}


    }
}
